使用VB6.0在Windows Vista下实现全磨砂玻璃窗口 - 枕善居VB.NET源码博客枕善居VB.NET源码博客 
首先我为人人,其次人人为我!
  首页
  乱侃
  公告
  VB源码
  .NET源码
  工具
  贴图
  原创
  论坛
  留言
  归档
欢迎光临:
　　
　　非常感谢您光临枕善居。本站是一个免费的基于VB，VB.NET源代码交流的平台，为大家提供优质的专业的源代码，如果您有需要，本站可以帮助在业余时间里给您寻找代码。当然，如果您有好的代码也可以在本站发布，共享给大家。
专业VB和.NET源代码DVD光盘、开发编程Icon,PNG、USB电脑遥控器，点击进入--->
 M2009 USB电脑遥控器 标准微软RC6格式 MCE格式设计 无线鼠标功能!            
VB及.NET源码文档+解决方案+数据字典DVD(控件升级DVD) 


      输入您的搜索字词  提交搜索表单         
 订阅 |  上一篇 |  下一篇  VB源码 使用VB6.0在Windows Vista下实现全磨砂玻璃窗口作者:Mndsoft 
日期:2006-08-17字体大小: 小 中 大  

作者:吴滂

使用过Windows Vista 的用户都会对Vista窗口的磨砂玻璃效果印象深刻，而如果你在Windows Vista 下使用过 Windows Media 
Player 11 更会发现微软把这种效果扩展至WMP11的底部区域，使得WMP的底部按钮区域成为一条“玻璃带”，如图：



事实上，Vista窗口的磨砂玻璃效果不仅限于窗体的边框（非客户区域），他可以任意的延伸，甚至铺满整个窗口，下面我们就来看看怎么用的vb6来实现这种扩展。
Vista实现磨砂玻璃效果主要依靠一组叫做 Desktop Window Manager (DWM) 
的API来实现，该组API均以dwm打头，存在于dwmapi.dll中（该文件为Vista特有），顾名思义，这些API是专门用来实现Vista窗口的特效的。由于篇幅所限，这里仅介绍和本文关系最密切的两个函数：DwmIsCompositionEnabled 
和 DwmExtendFrameIntoClientArea。
第一个函数DwmIsCompositionEnabled是用于判断系统的磨砂玻璃合成效果是否已经开启，因为该效果可以由用户关闭，尽管你可以在用户关闭合成效果的情况下在程序中单独使用合成效果。



DwmIsCompositionEnabled的原型为：
HRESULT DwmIsCompositionEnabled( BOOL *pfEnabled )
其中pfEnabled为一个输出参数，告诉后面的程序合成效果是否被打开。
该函数的VB声明为：
Public Declare Function DwmIsCompositionEnabled Lib "dwmapi.dll" (ByRef 
enabledptr As Long) As Long
这里要注意C++里的BOOL类型必须译成vb中的Long而不是Boolean，否则你将得到错误的结果。
DwmExtendFrameIntoClientArea函数则用于将磨砂边框扩展至窗体客户区，使得整个窗体看上就像一张卡片(sheet)。
该函数原型为：
HRESULT DwmExtendFrameIntoClientArea(HWND hWnd,const MARGINS *margins)
其中hWnd 为目标窗口句柄，margins为一个MARGINS结构体指针

MARGINS结构体定义为：
typedef struct _MARGINS 
{ 
int cxLeftWidth; 
int cxRightWidth; 
int cyTopHeight; 
int cyBottomHeight;
} MARGINS, *PMARGINS;

该函数的vb引用为：
Public Declare Function DwmExtendFrameIntoClientArea Lib "dwmapi.dll" (ByVal 
hwnd As Long, margin As MARGINS) As Long

MARGINS的vb形式定义：
Public Type MARGINS
m_Left As Long
m_Right As Long
m_Top As Long
   m_Button As Long
End Type
其中MARGINS中的各个成员为需要扩展的边框大小（单位：像素），如果要把磨砂玻璃效果铺满整个边框（本文以此为例），全部成员可设置为-1

知道了这些，我们现在就可以动手了。
我们在窗体的Form_Load事件里写上：
Dim mg As MARGINS, en As Long
    mg.m_Left = -1
    mg.m_Button = -1
    mg.m_Right = -1
    mg.m_Top = -1
     
    DwmIsCompositionEnabled en
    If en Then
        
        DwmExtendFrameIntoClientArea Me.hwnd, mg
        

    End If

然后运行（先确保系统使用Aero界面且合成效果被打开），结果发现窗体依然如故。原来，DwmExtendFrameIntoClientArea扩展后的边框并不会在客户区的前景显示（它其实是一个背景，你会发现，此时边框其实已经被扩展了，因为原来的客户区的凹陷边界已经消失），磨砂玻璃的效果被窗体默认画上去的前景覆盖了，所以我们得自己给窗体画个“透明”的前景。幸运的是，在RGB调色版中，黑色black 
(0x00000000)刚好就是ARGB（short for Alpha, Red, Green and 
Blue）的100%透明（这刚好可以解释为什么用Windows 
画图板打开一个png图片时透明背景会变成纯黑）。所以，第一个方法，我们可以在窗口的Form_Paint事件（是的，Form_Paint就足够了，不用去子类化窗体。当然，如果要实现更高级功能，还是子类化吧…）中给窗口的前景用纯黑(RGB(0,0,0))填充，用的是经典的GDI，主要就是CreateSolidBrush和FillRect两个API工作，代码：
Dim hBrush As Long, m_Rect As RECT, hBrushOld As Long
    hBrush = CreateSolidBrush(RGB(0, 0, 0))
    hBrushOld = SelectObject(Me.hdc, hBrush)
    GetClientRect Me.hwnd, m_Rect

    FillRect Me.hdc, m_Rect, hBrush
    SelectObject Me.hdc, hBrushOld

    DeleteObject hBrush   ‘别忘了删除对象

现在再按一次F5，恩….很好！效果如下：



但是接着问题就来了，当你在窗体上放上几个控件之后会发现，控件的黑色部分（一般就是文字）也带上了磨砂玻璃的“特效”，如图：



注意到上面的Text1文字了吗？这种效果可不是我们想要的。怎么办呢？

上帝说：要有更好的办法
于是，就有了第二种实现方法。


其实这个问题的关键是画出透明的客户区，那么，别忘了，还有一个API可以做成此事，记得.NET里面那些控件和窗口有的有个TransparentKey属性么？没错了，就是用它—— 
SetLayeredWindowAttributes
SetLayeredWindowAttributes可以提供这样的一个功能：给一个窗口设定一个透明色，然后窗口显示的时候指定颜色的区域将变成透明。这样，只要我们给窗口指定一种没有用到的颜色（反正不是黑色就行，这里我用RGB(255,255,1)），就可以“画”出“透明”的区域了。
我们在使用之前要先对SetLayeredWindowAttributes做做手脚，将其声明为：
Public Declare Function SetLayeredWindowAttributesByColor Lib "user32" Alias 
"SetLayeredWindowAttributes" (ByVal hwnd As Long, ByVal crey As Long, ByVal 
bAlpha As Byte, ByVal dwFlags As Long) As Long

为什么要这么干呢？留意函数第二个参数，本来有人将其声明为Byte类型（用于窗体半透明时没有问题），但是这里要传一个RGB值，所以要改成Long
代码如下，相关的API和常量不再敷述，声明和值请读者自行补齐

Form_Load事件：(先声明m_transparencyKey全局变量，Long类型)


m_transparencyKey = RGB(255, 255, 1)    ‘多少没所谓
    SetWindowLong Me.hwnd, GWL_EXSTYLE, GetWindowLong(Me.hwnd, GWL_EXSTYLE) or 
WS_EX_LAYERED
    SetLayeredWindowAttributesByColor Me.hwnd, m_transparencyKey, 0, 
LWA_COLORKEY

    Dim mg As MARGINS, en As Long
    mg.m_Left = -1
    mg.m_Button = -1
    mg.m_Right = -1
    mg.m_Top = -1
    MsgBox "1"
    DwmIsCompositionEnabled en
    If en Then
               DwmExtendFrameIntoClientArea Me.hwnd, mg
              
    End If



再在Form_Paint事件中画图：

Form_Paint代码：

Dim hBrush As Long, m_Rect As RECT, hBrushOld As Long
    hBrush = CreateSolidBrush(m_transparencyKey)
    hBrushOld = SelectObject(Me.hdc, hBrush)
    GetClientRect Me.hwnd, m_Rect

    FillRect Me.hdc, m_Rect, hBrush
    SelectObject Me.hdc, hBrushOld

    DeleteObject hBrush


再按F5，效果嘛……



顺便提一下，此代码在Windows Vista以下版本，2000及以上Windows版本运行时会产生一个很有趣的效果（除控件外窗体客户区背景完全透明！），如图：



当然，DWM API的功能还远不止这些，本文仅介绍了少部分功能而已。


【VB和.NET专业源码+解决方案+数据字典DVD(全国包快递)】 代码清单 购买后可以享受认证VIP会员及免费获取破解控件补丁

 点击下载    站外 本站        [本日志由 Mndsoft 于 2007-10-25 10:12 PM 编辑]

文章来自: 吴滂
引用通告地址: 查看引用地址
Tags: 窗口窗口 VistaVista 界面界面 
相关日志:

99%的Vista Aero窗体VB源码[9886]
模仿VistaAero透明窗体源码[7495]
效果很棒的VB.NET2005界面控件(iForm V3)[13159]
300多个 Vista 使用的 Ico图标[19516]
14种动画窗口加载和关闭特效示例[7642]
界面清爽VB版高级专业防火墙 Ver 2.0.3[12024]
两款透明和非透明Vista窗体控件比较[11003]
包含17个源码的图形界面的经典控件包[17649]
Vista界面模仿窗体示例(修正版)[10831]
Vista界面精美时钟控件源代码 Ver 1.0[8741]
分页: [1][2][3][4][5]
模式: 全部显示[共42个相关文章]
  其他日志热门日志 相关日志 最新日志 随机日志 人气日志 电脑新奇特 源码商店 
抛弃微软附带控件，打造个性控件，全部源码！[29052]
串口通信编程大全[23834]
精简版的MSDN　for VB6.0[23625]
豪华的界面控件---NiceFormControl[30068]
网友下载须知(2006-06-26)！！！！！！！！！[13591]
企业人事管理系统完美版[20636]
300多个 Vista 使用的 Ico图标[19516]
请购买本站物品的网友提供您的论坛ID,免费进入破解补丁版块[9780]
给鼠标添件防寒外套,买暖手鼠标垫送源码光盘![10309]
三千多个精美OFFICE2007图标(16x16)[22991]
超薄 免驱动 USB电脑遥控器 完美支持Windows Vista 
http://auction1.taobao.com/auction/item_detail-0db1-d33a3125adc7a851f7b8cbe75647e346.jhtml
枕善居精品源码网站：http://shop34161785.taobao.com/ 支持支付宝在线支付
评论: 22 | 引用: 0 | 查看次数: 15371 1 | 2 | 3 | >Terryzhong28 [2009-04-25 08:42 
AM]有没有VB.NET的呀yz99 [2008-03-19 07:23 PM]好办法你d农村 你们才能把你好美女   
敏感话题不nhmf黄金版你不够好让美女不仅耗费干部功能不好 级你特别 不能个vhjfgh 不jgn dabian001 [2008-03-03 05:03 
PM]少了这个文件dwmapi.dll

运行失败!ajan [2007-06-26 01:16 PM]
  少了这个文件dwmapi.dll

运行失败!Bean [2007-05-13 02:49 PM]看起来很漂亮啊 大佬wp [2006-12-28 01:35 
PM]是的,在RC1以后的版本里面只能试用黑色填充的方法而不能使用TransparentKey方法了AresVista [2006-12-16 02:25 
PM]在 Vista 正式版下得到的只是黑色背景,玻璃效果出不来squallhnyn [2006-12-02 00:10 AM]我也看看甚么样子mirage 
[2006-09-13 04:54 AM]微軟慘絕人寰阿！
其實想在Xp/2K/2K3中實現
Vbgood中有人討論過
就是在窗體上重繪窗體下面的東西
給與磨砂效果
只是CPU占用过高
用Timer控件来重复绘制
效果不是很理想!joforn [2006-09-11 04:23 PM]强，下载看看 1 | 2 | 3 | >发表评论昵　称:
      内　容:








      选　项:禁止表情转换 禁止自动转换链接 禁止自动转换关键字 
         
      字数限制 1000 字 | UBB代码 开启 | [img]标签 关闭 





控制面板yxxxxxxx，欢迎您!
您的权限: 普通会员


修改资料退出系統相关日志-加强版
最新日志Visual Studio 2..电信大客户查询系统 Ver 
1..媲美微软画图的画图源代码彩色图形复选框(CheckBo..1600多个精美编程开发用PN..JCButton按钮控件(完美..多文档选项卡控件示例(jcMD..笔记本电池监控器 
Ver 1...双曲线绘图控件源代码堆栈计算器最新评论[smile]这个控件好用谢谢 ！这个控件是免费的吗？没啥使用限制吧？nice flowersthanks 
a loat非常感谢，我一直想找这方面的源码。谢谢了我怎么才发现这个空间呢？  真是一大损失我看还是兼容性的问题。 
VISTA是个失败的操作...太喜欢了。。哈哈你好楼主。    编译错误  请楼主改一下 
最新留言[b]请问管理员同志，能不能帮我找一下像灰鸽子那样...各位大侠。有没有关于VB 写的 
企业所需的BOM清...最近实在太忙了，小站都好久没有更新。这两天把PJ升...我想实现这样的结果：当你对着麦克风说话时，能实时的...居士: 
有没有一个日期&#43;时间,好...居士，麻烦您帮我找一些关于VB&#43;A...今天在淘宝上订购了一套光盘,订购名为俞红斌,请将我...我想用vb做一个能自行设置字段的打印，现在我能做的...你好!你能不能制作一个像TVKOO的播放器.下载到...来看你拉，上茶 
多坐一会 哈哈 你网站人气也不错呀...日志归档枕善居VB源码博客2009年五月 [1]2009年四月 [9]2009年三月 [3]2009年二月 
  [3]2009年一月 [2]2008年十二月 [7]2008年十一月 [3]2008年十月 [2]2008年八月 [3]2008年七月 
  [12]2008年六月 [4]2008年五月 [11]2008年四月 [7]2008年三月 [9]2008年二月 [4]2008年一月 
  [15]2007年十二月 [12]2007年十一月 [16]2007年十月 [12]2007年九月 [22]2007年八月 [22]2007年七月 
  [18]2007年六月 [18]2007年五月 [41]2007年四月 [28]2007年二月 [12]2007年一月 [17]2006年十二月 
  [31]2006年十一月 [23]2006年十月 [23]2006年九月 [17]2006年八月 [8]2006年七月 [20]2006年六月 
  [28]2006年五月 [29]2006年四月 [46]2006年三月 [20]2006年二月 [31]2006年一月 [20]2005年十二月 
  [19]2005年九月 [9]2005年八月 [34]2005年七月 [42]2005年六月 [67]2005年五月 [106]2005年四月 
  [92]2005年三月 [96]2005年二月 [25]2005年一月 [25]
技术支持      
本站Logo本站中文名称:
枕善居VB源码博客
链接地址:
http://www.mndsoft.com
描述:枕善居一个专业发布VB源代码的博客,有问必答，帮助大伙学习的站点。尤其是初学者要去的地方，当然，老鸟也能从那里挖到宝藏:) 
LOGO:
 
Powered By PJBlog2 v2.6 build 03 CopyRight 2005, 枕善居VB.NET源码博客 xhtml | css
Processed in 0.406250 second(s) , 5 queries , Ilive Design By waeko 
浙ICP备05018754号 
站长统计 | 今日IP[250] | 今日PV[3608] | 昨日IP[811] | 昨日PV[24770] | 当前在线[19]  